﻿using System;
using System.IO;
using System.Net;
using System.Threading;
using System.Windows.Forms;

namespace pkgman
{
    public partial class updMain : Form
    {
        HttpWebRequest webRequest;
        HttpWebResponse webResponse;
        FtpWebRequest ftpRequest;
        FtpWebResponse ftpResponse;
        Stream strResponse;
        FileStream strLocal;
        private long fileSize;

        public byte[] setupbuffer(Int64 Filesize)
        {
            int buffers = 4096;
            if (Filesize > 300 * 1048576) buffers = 4 * 1048576;//4mb buffer
            else if (Filesize > 100 * 1048576) buffers = 1048576; //1Mb buffer
            else if (Filesize > 50 * 1048576) buffers = 512 * 1024; //512kb buffer;
            else if (Filesize > 20 * 1048576) buffers = 128 * 1024; // 128kb buffer
            else if (Filesize > 5242880) buffers = 16 * 1024; //16kb buffer;
            return new byte[buffers];
        }
        private string DFileSize(Int64 fsize)
        {
            double outp;
            if (fsize > 1073741824)
            {
                outp = ((double)fsize / 1073741824);
                outp = Math.Round(outp, 2);
                return outp.ToString() + " Gib";
            }
            else if (fsize > 1048576)
            {
                outp = ((double)fsize / 1048576);
                outp = Math.Round(outp, 2);
                return outp.ToString() + " Mib";
            }
            else if (fsize > 1024)
            {
                outp = ((double)fsize / 1024);
                outp = Math.Round(outp, 2);
                return outp.ToString() + " Kib";
            }
            else return fsize.ToString() + " byte";
        }

        private void setupHTTP(string url, NetworkCredential UserPass)
        {
            webRequest = null;
            webResponse = null;
            webRequest = (HttpWebRequest)WebRequest.Create(url);
            if (WebRequest.GetSystemWebProxy() != null) webRequest.Proxy = WebRequest.GetSystemWebProxy();
            webRequest.Credentials = UserPass;
            if (url.StartsWith("https://")) ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
            webResponse = (HttpWebResponse)webRequest.GetResponse();
            if (webResponse.ResponseUri.ToString() != url)
            {
                setupHTTP(webResponse.ResponseUri.ToString(), UserPass);
            }
            fileSize = webResponse.ContentLength;
            strResponse = webResponse.GetResponseStream();
        }

        private void setupFTP(string url, NetworkCredential UserPass)
        {
            ftpRequest = null;
            ftpResponse = null;
            // get file size ->
            ftpRequest = (FtpWebRequest)WebRequest.Create(url);
            ftpRequest.Credentials = UserPass;
            if (WebRequest.GetSystemWebProxy() != null) ftpRequest.Proxy = WebRequest.GetSystemWebProxy();
            ftpRequest.Method = WebRequestMethods.Ftp.GetFileSize;
            ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
            fileSize = ftpResponse.ContentLength;
            // download ->
            ftpRequest = (FtpWebRequest)WebRequest.Create(url);
            ftpRequest.Credentials = UserPass;
            if (WebRequest.GetSystemWebProxy() != null) ftpRequest.Proxy = WebRequest.GetSystemWebProxy();
            ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
            ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
            strResponse = ftpResponse.GetResponseStream();
        }

        private void Download()
        {
            bool isftp;
            NetworkCredential UserPass;
            string dest;
            string[] tmp1, userpass;
            int cnt = 0;
            string url;

            url = threadpars[0];
            strLocal = null;
            strResponse = null;
            isftp = url.StartsWith("ftp://");

            tmp1 = url.Split('@'); //-> tmp1[1] path
            if (tmp1.Length < 2) UserPass = new NetworkCredential("anonymous", "csharpdltool@csharpdltool.com");
            else
            {
                userpass = tmp1[0].Split(':');
                UserPass = new NetworkCredential(userpass[1].Replace("//", @""), userpass[2]);
            }
            using (WebClient wcDownload = new WebClient())
            {
                Thread.Sleep(100);
                try
                {
                    try
                    {
                        if (!isftp)
                        {
                            this.setupHTTP(url, UserPass);
                            url = webResponse.ResponseUri.ToString();
                        }
                        else this.setupFTP(url, UserPass);
                        dest = threadpars[1];
                        strLocal = File.Create(dest);
                        int bytesSize = 0;
                        byte[] downBuffer = this.setupbuffer(fileSize);

                        if (back.IsAlive)
                        {
                            while ((bytesSize = strResponse.Read(downBuffer, 0, downBuffer.Length)) > 0)
                            {
                                strLocal.Write(downBuffer, 0, bytesSize);
                                //this.Invoke(new UpdateProgessCallback(this.UpdateProgress), new object[] { strLocal.Length, fileSize, cnt });
                            }
                        }
                    }
                    catch (WebException exp)
                    {
                        MessageBox.Show("The folowing error occured: " + exp.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                catch (IOException ex)
                {
                    MessageBox.Show("The folowing error occured: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {
                    if (strResponse != null)
                    {
                        strResponse.Flush();
                        strResponse.Close();
                        strResponse = null;
                    }
                    if (strLocal != null)
                    {
                        strLocal.Close();
                        strLocal = null;
                    }
                    ++cnt;
                }
            }
        }
    }
}
